package com.wxy.livebroadcast.service;


import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.wxy.livebroadcast.entity.JsonObj;
import com.wxy.livebroadcast.entity.UserEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.time.Instant;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.TimeUnit;

@ServerEndpoint("/websocket/oneToMany")
@Component
@Slf4j
public class WebSocketServer {
    private static int onlineCount = 0;
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet();
    private static Map<WebSocketServer, Instant> userMap = new HashMap();
    private static List<JsonObj> msgList = new ArrayList();
    public Session session;
    public String name = "";
    public String url = "";
    @Resource
    private SocketService socketService;

    /**
    * 连接建立成功调用的方法
     * */
    @OnOpen
    public void onOpen(Session session) {
        Map<String, List<String>> map = session.getRequestParameterMap();
        String name = (String)((List)map.get("name")).get(0);
        String url = (String)((List)map.get("url")).get(0);
        if ((name == null) || ("".equals(name))) {
            return;
        }
        for (WebSocketServer server : webSocketSet) {
            if (server.name.equals(name)) {
                return;
            }
        }
        this.session = session;
        this.name = name;
        this.url = url;
        webSocketSet.add(this);

        log.info("有新窗口开始监听设备:" + name);
        if (!"aW5kZXgNCg==".equals(name)) {
            for (WebSocketServer server : webSocketSet) {
                if (server.name.equals("aW5kZXgNCg==")) {
                    try
                    {
                        server.sendMessage("reload");
                    }
                    catch (IOException e)
                    {
                        log.error("websocket IO异常");
                    }
                }
            }
        }
    }

/**
 * 连接关闭调用的方法
 */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
//        subOnlineCount();           //在线数减1
        log.info(this.name + "设备断开！");

        // 发送重载消息
        for (WebSocketServer server : webSocketSet){
            if (server.name.equals("aW5kZXgNCg==")){
                // 给主页推送消息
                try {
                    server.sendMessage("reload");
                } catch (IOException e) {
                    log.error("websocket IO异常");
                }
            }
        }
    }

/**
 * 收到客户端消息后调用的方法
 *
 * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到来自设备" + this.name + "的消息:" + message);
        if (StrUtil.isEmpty(this.name)) {
            return;
        }
        if ("heart_beat".equals(message))
        {
            userMap.put(this, Instant.now().plusMillis(TimeUnit.HOURS.toMillis(8L)));
            return;
        }
        JsonObj jsonObj = new JsonObj();
        jsonObj.setName(this.name);
        jsonObj.setContent(message);
        msgList.add(jsonObj);
        for (WebSocketServer server : webSocketSet) {
            if (server.name.equals("aW5kZXgNCg==")) {
                try
                {
                    server.sendMessage(JSON.toJSONString(msgList));
                }
                catch (IOException e)
                {
                    log.error("websocket IO异常");
                }
            }
        }
    }

/**
 *
 * @param session
 * @param error
 */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
    }

/**
 * 实现服务器主动推送
 */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

/**
 * 群发自定义消息
 * */
    public static void sendInfo(String message, String name) throws IOException {
        if (message == null || ("").equals(message)){
            throw new IOException();
        }
        log.info("推送消息到设备"+name+"，推送内容:"+message);
        boolean flag = false;
        for (WebSocketServer item : webSocketSet) {
            if(item.name.equals(name)){
                item.sendMessage(message);
                flag = true;
            }
        }
        if (!flag){
            throw new IOException();
        }
    }

    public static void reload()
    {
        for (WebSocketServer server : webSocketSet) {
            if (server.name.equals("aW5kZXgNCg==")) {
                try
                {
                    server.sendMessage("reload");
                }
                catch (IOException e)
                {
                    log.error("websocket IO异常");
                }
            }
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }
    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }
    public static CopyOnWriteArraySet<WebSocketServer> getWebSocketSet() {
        return webSocketSet;
    }

    public static Map<WebSocketServer, Instant> getUserMap()
    {
        return userMap;
    }

    public static UserEntity getUser(String name)
    {
        for (WebSocketServer server : webSocketSet) {
            if (name.equals(server.name))
            {
                UserEntity userEntity = new UserEntity();
                userEntity.setName(server.name);
                userEntity.setUrl(server.url);
                return userEntity;
            }
        }
        return null;
    }

    public static List<JsonObj> getMsgList()
    {
        return msgList;
    }
}
